home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
476-500
/
500
/
wiconify
/
wiconsetter.lzh
/
wIconSetter
/
Source
/
wIconFileIO.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-19
|
13KB
|
559 lines
/*
* WICONSETTER A companion utility to wIconify. wIconSetter allows
* you to specify custom icons for windows ans screens
* that normally use the default icons.
*
* wIconFileIO.c Handles low-level file activity.
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#include <exec/types.h>
#include <stdio.h>
#include "wIconFile.h"
FILE *InFile; /* Main file pointer */
int EndOfFile; /* TRUE if at end-of-file */
static int LineCount; /* Number of lines read */
static char Line[MAXLINE+2]; /* Line buffer */
static short LinePos; /* current position in line */
static short WrdStart,WrdEnd; /* Where the current word starts and ends */
char NextChar; /* the next character of the file */
char Word[MAXLINE+1]; /* the word buffer */
static FILE *OldFile; /* Saved file for DEFAULT_ICON command */
static int OldLineCount; /* Saved line count for old file */
#define INVERSE "\033[32;41m"
#define NORMAL "\033[m"
#define COLORED "\033[32;40m"
/*
* ShowError()
*
* If the word starts and ends at the same character, move ahead so something
* will be displayed.
* Get the first character of the word, and end the line there.
* Set the text color and print the first part of the line.
* Put back the first character of the word, and save the last one.
* Print the word in inverted lettering and go back to colored letters.
* Put back the last letter of the word and print the rest of the line.
* Go back to normal lettering and print the error message with a line number.
* If the icon file is open, indicate that.
*/
void ShowError(s,x1,x2,x3)
char *s,*x1,*x2,*x3;
{
char c;
if (WrdStart == WrdEnd) WrdEnd++;
c = Line[WrdStart]; Line[WrdStart] = 0;
printf(COLORED);
printf("%s",Line);
Line[WrdStart] = c; c = Line[WrdEnd]; Line[WrdEnd] = 0;
printf(INVERSE);
if (EndOfFile || Line[WrdStart] < ' ') printf(" ");
else printf("%s",&Line[WrdStart]);
printf(COLORED);
Line[WrdEnd] = c; if (c) printf("%s",&Line[WrdEnd]); else printf("\n");
printf(NORMAL);
printf(s,x1,x2,x3);
printf(" at line %d",LineCount);
if (OldFile) printf(" of Icon File");
printf("\n");
}
/*
* Expected()
*
* If we are at the end of file, indicate this.
* If the word is a single character (or no characters)
* If the character is printable, use it,
* Otherwise, convert it to a word it control character notation.
* Print the message saying what was seen and what was expected.
*/
void Expected(s)
char *s;
{
char *Seen = &Word[0];
char c = Line[WrdStart];
if (EndOfFile) Seen = "End-of-File"; else
if (WrdEnd < WrdStart+2)
{
if ((c >= ' ' && c < 0x7F) || c > 0xA0) Seen = " ", Seen[0] = c;
else
{
switch(c)
{
case '\n':
Seen = "End-of-Line";
break;
case ' ':
Seen = "Space";
break;
case '\t':
Seen = "TAB";
break;
case '\033':
Seen = "ESC";
break;
case '\0':
Seen = "NULL";
break;
case 0x7F:
Seen = "DEL";
break;
default:
Seen = "^ ";
Seen[1] = (c & 0x1F) + '@';
break;
}
}
}
ShowError("'%s' seen where %s was expected",Seen,s);
}
/*
* GetNextLine()
*
* If we can read a line from the file,
* Mark the end of line (in case the maximum of the buffer was used)
* Clear the position markers, and count the line.
* Get the next character on the line.
* Otherwise,
* Clear the line and set the positions to the end of the line.
* Mark the end of file (any error is treated as EOF).
*/
static void GetNextLine()
{
if (fgets(Line,MAXLINE,InFile))
{
Line[MAXLINE] = '\n';
Line[MAXLINE+1] = 0;
LinePos = WrdStart = WrdEnd = 0;
LineCount++;
NextChar = Line[LinePos];
} else {
NextChar = '\n'; LinePos = WrdStart = WrdEnd = MAXLINE;
EndOfFile = TRUE;
}
}
/*
* GetNextChar()
*
* Get the next character on the line and increment the position.
* Set the word positions to the current position.
*/
void GetNextChar()
{
NextChar = Line[++LinePos];
WrdStart = WrdEnd = LinePos;
}
/*
* SkipComments()
*
* While we are at the beginning of a comment (indicated by '/*')
* Move past the comment characters and increment the comment counter
* Get the next character.
* While we are still within a coment,
* and until we reach a comment terminator or end-of-file,
* If we are at the end of a line, read the next line,
* If we are at the beginning of a nested comment,
* Increment the nexted count and move past the comment characters.
* Otherwise, go on to the next character.
* If we are at the end of the file, show an error (unbalanced comments).
* Otherwise, skip the end-comment characters.
* Decrement the comment nesting count.
* If the next character is the rest-of-line comment character,
* or if we are at the end of the file, move to the end of the line.
*/
void SkipComments()
{
int Nested = 0;
while (NextChar == '/' && Line[LinePos+1] == '*')
{
LinePos += 2; Nested++;
NextChar = Line[LinePos++];
while (Nested)
{
while ((NextChar != '*' || Line[LinePos] != '/') && !EndOfFile)
{
if (NextChar == '\n' || NextChar == '\0') GetNextLine(); else
if (NextChar == '/' && Line[LinePos] == '*')
Nested++, NextChar = Line[++LinePos];
else NextChar = Line[LinePos++];
}
if (EndOfFile)
{
WrdStart = WrdEnd = MAXLINE;
Expected("End-of-Comment");
} else NextChar = Line[++LinePos];
Nested--;
}
}
if (EndOfFile || NextChar == ';') NextChar = Line[LinePos=MAXLINE];
}
/*
* SkipSpaces()
*
* First skip any comments.
* While the next character is white-space,
* Skip characters until it is not white space,
* Then skip comments and do it again.
*/
void SkipSpaces()
{
SkipComments();
while (NextChar == ' ' || NextChar == '\t')
{
do NextChar = Line[++LinePos];
while (NextChar == ' ' || NextChar == '\t');
SkipComments();
}
}
/*
* ReadNextLine()
*
* While there is more in the file, and the current line is blank
* Get the next line of the file and skip any comments.
* Do this until there is actually some real data to look at.
* Set the word positions to the current location.
*/
void ReadNextLine()
{
while (!EndOfFile && (NextChar == 0 || NextChar == '\n'))
{
GetNextLine();
SkipSpaces();
}
WrdStart = WrdEnd = LinePos;
}
/*
* SkipChar()
*
* If we are at the end of the line, read the next one,
* Otherwise, move to the next non-blank character.
*/
void SkipChar()
{
if (NextChar == '\n') ReadNextLine();
else NextChar = Line[++LinePos], SkipSpaces();
}
/*
* SkipLine()
*
* No matter where we are on the current line, go on to the next line
* and skip spaces. Mark the current word positions.
*/
void SkipLine()
{
GetNextLine(); SkipSpaces();
WrdStart = WrdEnd = LinePos;
}
/*
* ReadNextChar()
*
* Get the next character and mark the beginning of a word.
* Skip any spaces after the current character.
*/
void ReadNextChar()
{
NextChar = Line[++LinePos];
WrdStart = WrdEnd = LinePos;
SkipSpaces();
}
/*
* ReadAWord()
*
* Begin the word at the current location.
* While the next character is a letter (or a number if they are allowed)
* Add it to the word buffer and go to the next character
* If the word has at least one character, mark the end of the word,
* Otherwise, the word is a single special character.
* Mark the end of the word in the line buffer and skip trailing spaces.
*/
void ReadAWord(Numbers)
int Numbers;
{
short i=0;
WrdStart = LinePos;
while ((NextChar >= 'A' && NextChar <= 'Z') ||
(NextChar >= 'a' && NextChar <= 'z') ||
(NextChar >= '0' && NextChar <= '9' && Numbers) ||
NextChar == '_')
{
Word[i++] = NextChar;
NextChar = Line[++LinePos];
}
if (i)
{
Word[i] = 0;
} else {
Word[0] = NextChar; Word[1] = 0;
NextChar = Line[++LinePos];
}
WrdEnd = LinePos;
SkipSpaces();
}
/*
* ReadNextWord()
*
* Read a word without allowing numbers as part of the word.
*/
void ReadNextWord()
{
ReadAWord(FALSE);
}
/*
* ReadExtendedWord()
*
* Read a word and allow numbers as part of the word.
*/
void ReadExtendedWord()
{
ReadAWord(TRUE);
}
/*
* ReadNextInteger()
*
* Get the first digit of the number.
* If it is a minus sign, add it to the number and move on.
* While the next character is a digit, add it to the number and move on.
* Mark the end of the word, and skip blanks.
*/
void ReadNextInteger()
{
short i=0;
NextChar = Line[LinePos=WrdStart];
if (NextChar == '-')
{
Word[i++] = NextChar;
NextChar = Line[++LinePos];
}
while (NextChar >= '0' && NextChar <= '9')
{
Word[i++] = NextChar;
NextChar = Line[++LinePos];
}
Word[i] = 0;
WrdEnd = LinePos;
SkipSpaces();
}
/*
* ReadFullLine()
*
* Get the first letter of the word.
* If the first character is a quote, flag it and move past it.
* While we are not at the end of the line (or at an end quote)
* Add the character into the word buffer and move on.
* If we are looking for a close quote
* and the next character is a quoted quote,
* add a single quote into the buffer and skip over the quotes.
* Mark the end of the word (ie, line).
* If we were looking for quotes, then
* If we didn't find a closing quote, show an error, otherwise skip
* over the close-quote.
* Skip blanks after the string.
* Otherwise, strip off trailing blanks from the string.
*/
void ReadFullLine()
{
short i = 0;
int Quoted = FALSE;
NextChar = Line[LinePos=WrdStart];
if (NextChar == '\'')
{
Quoted = TRUE;
NextChar = Line[WrdStart=++LinePos];
}
while (NextChar != '\n' && (NextChar != '\'' || Quoted == FALSE))
{
Word[i++] = NextChar;
NextChar = Line[++LinePos];
if (Quoted)
{
if (NextChar == '\'' && Line[LinePos+1] == '\'')
{
Word[i++] = NextChar;
LinePos += 2;
NextChar = Line[LinePos];
}
}
}
WrdEnd = LinePos;
Word[i--] = 0;
if (Quoted)
{
if (NextChar == '\n') ShowError("Quoted string not terminated");
else NextChar = Line[++LinePos];
SkipSpaces();
} else {
while (i >= 0 && Word[i] == ' ') Word[i--] = 0;
}
}
/*
* Reread()
*
* Go back to be beginning of the word and start reading again.
*/
void Reread()
{
LinePos = WrdStart;
NextChar = Line[LinePos];
}
/*
* WordToUpper()
*
* Look through the word buffer and convert lower case letters to uppper
* case ones.
*/
void WordToUpper()
{
char *s = &Word[0];
while (*s)
{
if (*s >= 'a' && *s <= 'z') *s = *s - 'a' + 'A';
s++;
}
}
/*
* OpenFile()
*
* Attempt to open the specified file.
* If successful,
* Set the error status and line counters and read the first line
* Return TRUE if file openned OK.
*/
int OpenFile(Name)
char *Name;
{
int status = FALSE;
InFile = fopen(Name,"r");
if (InFile)
{
EndOfFile = FALSE; LineCount = 0;
ReadNextLine();
status = TRUE;
}
return(status);
}
/*
* CloseFile()
*
* Close the file and clear the file pointer.
*/
void CloseFile(theFile)
FILE *theFile;
{
fclose(theFile);
if (theFile == InFile) InFile = NULL;
}
/*
* SaveOpenFile()
*
* Save the old file pointer and old line count.
* Clear the file pointer for future use.
*/
void SaveOpenFile()
{
OldFile = InFile;
OldLineCount = LineCount;
InFile = NULL;
}
/*
* RestoreFile()
*
* If there was an old file open,
* Get back the old pointer and line count,
* Reset the status, and move to the end of the line.
* Clear the save pointer for future use.
*/
void RestoreFile()
{
if (OldFile)
{
InFile = OldFile;
LineCount = OldLineCount;
EndOfFile = FALSE;
NextChar = Line[LinePos=MAXLINE];
OldFile = NULL;
}
}